package com.snail.generator.controller;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.snail.generator.common.R;
import com.snail.generator.common.WebContext;
import com.snail.generator.entity.TableInfo;
import com.snail.generator.mapper.GeneratorMapper;
import com.snail.generator.utils.GenUtils;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@Slf4j
@RequestMapping("/api/gen")
@RestController
@RequiredArgsConstructor
public class GeneratorController {
    private final ObjectMapper objectMapper;

    @PostMapping("/database")
    public R<List<String>> getDatabases() {
        GeneratorMapper generatorMapper = WebContext.getGeneratorMapper();
        return R.success(generatorMapper.queryDatabase());
    }

    @PostMapping("/table")
    public R<List<TableInfo>> getTables() {
        GeneratorMapper generatorMapper = WebContext.getGeneratorMapper();
        return R.success(generatorMapper.queryTable());
    }

    @PostMapping("/generateCode")
    @SneakyThrows
    public void generateCode(@RequestParam String packages, @RequestParam String module, String tablePrefix,
                             @RequestParam String tables, HttpServletResponse response) {
        List<TableInfo> tableInfos = objectMapper.readValue(tables, new TypeReference<>() {});
        validParams(packages, module, tableInfos);

        byte[] data = GenUtils.generateCode(packages, module, tablePrefix, tableInfos);

        response.reset();
        response.setHeader("Content-Disposition", "attachment; filename=\"generate-code.zip\"");
        response.addHeader("Content-Length", "" + data.length);
        response.setContentType("application/octet-stream; charset=UTF-8");

        IOUtils.write(data, response.getOutputStream());
    }

    private void validParams(String packageName, String module, List<TableInfo> tables) {
        if (!packageName.matches("[a-zA-Z_][a-zA-Z0-9_]*(?:\\.[a-zA-Z_][a-zA-Z0-9_]*)*")) throw new IllegalArgumentException("包名不合法");
        if (!module.matches("[a-zA-Z_][a-zA-Z0-9_]*")) throw new IllegalArgumentException("模块名不合法");
        if (tables.isEmpty()) throw new IllegalArgumentException("请选择要生成的表");
    }

}
